/////precompiled////////
#include "precompiled.h"
////////////////////////


#include "prs_Attr.h"
using namespace prs;

// TAttr //////////////////////////////////////////////////////////////////////

//
TAttr::TAttr(TAttrNode *Node) : node(*Node) 
{
  node.AddAttr(this);
}

//
int TAttr::GetN()
{
  return node.GetN(this);
}

/**********
//
bool TAttr::GetValueByAttrName(svl::TString &AttrName,svl::TString &Value)
{
  if (AttrName.CompareIC(GetAttrName())) {
    Value = GetValueAsString();
    return true;
  }
  return false;
}
*************/
///////////////////////////////////////////////////////////////////////////////

//
TNode *prs::SearchNearParentByNodeType(TNode *FromChild,const char *ParentNodeType)
{
  return TNodeSearch(FromChild)
   .SearchNearParentByAttrNameAndValue(attrName_NodeType,ParentNodeType)
     .GetFirst();
}

//
bool prs::IsEqualNodeType(TAttrNodeTypeBase &NodeType1,const char *NodeType2) 
{ 
  return svl::TString(NodeType1.GetValue()).CompareIC((char*)NodeType2);
}

// TAttrPointerBase ///////////////////////////////////////////////////////////

/****************
//
TNode &TAttrPointerBase::GetNodeAttr() 
{ 
  return TAttr::GetNode();
}
***************/

/***************
// TAttrSysParam //////////////////////////////////////////////////////////////

//
void TAttrSysParam::CallChildrenFunc(TAttrUserParam &UserParam)
{
  node->CallChildrenFunc(func.GetAttrName(),UserParam);
}
******************/

/***********************************
// TAttrArray /////////////////////////////////////////////////////////////////

//
bool TAttrArray::GetValueByAttrName(svl::TString &AttrName,svl::TString &Value)
{
  for (int N = 0; N < Count(); N++) {
    if (Get(N).GetValueByAttrName(AttrName,Value)) {
      return true;
    }
  }
  return false;
}

//
bool TAttrArray::GetValueNodeByAttrName(svl::TString &AttrName,TNode *&Value)
{
  for (int N = 0; N < Count(); N++) {
    if (Get(N).GetValueNodeByAttrName(AttrName,Value)) {
      return true;
    }
  }
  return false;
}

//
bool TAttrArray::GetValueNodeArrayByAttrName(svl::TString &AttrName,TNodeArray *&Value)
{
  for (int N = 0; N < Count(); N++) {
    if (Get(N).GetValueNodeArrayByAttrName(AttrName,Value)) {
      return true;
    }
  }
  return false;
}

//
void TAttrArray::AddAttrPointer(TNode::TAddAttrPointer &Param) 
{
  for (int N = 0; N < Count(); N++) {
    Get(N).AddAttrPointer(Param);
  }
}

//
void TAttrArray::AddPossibleReferences(TNode::TAddPossibleReferences &Param)
{
  for (int N = 0; N < Count(); N++) {
    Get(N).AddPossibleReferences(Param);
  }
}

//
void TAttrArray::Accept(svl::IBaseVisitor &Visitor)
{
  for (int N = 0; N < Count(); N++) {
    Get(N).Accept(Visitor);
  }
}

//
void TAttrArray::GetChildrenArrays(TNodeChildrenArrays &Arrays)
{
  for (int N = 0; N < Count(); N++) {
    Get(N).TAttr_GetChildrenArrays(Arrays);
  }
}

//
void TAttrArray::GetChildrenNodes(TNodeChildrenNodes &Nodes)
{
  for (int N = 0; N < Count(); N++) {
    Get(N).TAttr_GetChildrenNodes(Nodes);
  }
}
******************************************/

// TAttrArray /////////////////////////////////////////////////////////////////

//
int TAttrArray::GetN(TAttr *Attr) { 
  for (int N = 0; N < a.Count(); N++) {
    TAttr *P = a.Get(N);
    if (P == Attr) {
      return N;
    }
  }
  Except("GetN[]");
  return 0;
}

//
bool TAttrArray::GetValueByAttrName(svl::TString &AttrName,svl::TString &Value)
{
  for (int N = 0; N < Count(); N++) {
    if (Get(N).GetValueByAttrName(AttrName,Value)) {
      return true;
    }
  }
  return false;
}

//
bool TAttrArray::GetValueNodeByAttrName(svl::TString &AttrName,TNode *&Value)
{
  for (int N = 0; N < Count(); N++) {
    if (Get(N).GetValueNodeByAttrName(AttrName,Value)) {
      return true;
    }
  }
  return false;
}

//
bool TAttrArray::GetValueNodeArrayByAttrName(svl::TString &AttrName,TNodeArray *&Value)
{
  for (int N = 0; N < Count(); N++) {
    if (Get(N).GetValueNodeArrayByAttrName(AttrName,Value)) {
      return true;
    }
  }
  return false;
}

//
void TAttrArray::AddAttrPointer(TNode::TAddAttrPointer &Param) 
{
  for (int N = 0; N < Count(); N++) {
    Get(N).AddAttrPointer(Param);
  }
}

//
void TAttrArray::AddPossibleReferences(TNode::TAddPossibleReferences &Param)
{
  for (int N = 0; N < Count(); N++) {
    Get(N).AddPossibleReferences(Param);
  }
}

//
void TAttrArray::Accept(svl::IBaseVisitor &Visitor)
{
  for (int N = 0; N < Count(); N++) {
    Get(N).Accept(Visitor);
  }
}

//
void TAttrArray::GetChildrenArrays(TNodeChildrenArrays &Arrays)
{
  for (int N = 0; N < Count(); N++) {
    Get(N).TAttr_GetChildrenArrays(Arrays);
  }
}

//
void TAttrArray::GetChildrenNodes(TNodeChildrenNodes &Nodes)
{
  for (int N = 0; N < Count(); N++) {
    Get(N).TAttr_GetChildrenNodes(Nodes);
  }
}







/***********************
// TAttrFuncBase //////////////////////////////////////////////////////////////

//
TAttrFuncBase::TAttrFuncBase(TAttrNode *Node,TFunc Func,bool EnDelete) : node(*Node)
{
  func = Func;
  node.AddFunc(this,EnDelete);
}
*************************/

// TAttrId ////////////////////////////////////////////////////////////////////

//
bool TAttrId::GetValueByAttrName(svl::TString &AttrName,svl::TString &Value) 
{
  if (AttrName.CompareIC(attrName())) {
    Value = value;
    return true;
  }
  return false;
}

//
TAttrNode *TAttrId::SearchByIdInParent(
  TNode       *InParent,
  svl::TString Id,
  bool         Recursive
)
{
  TNode *P = TNodeSearch(InParent)
   .SearchChildren()
    .SearchById(Id,Recursive)
      .GetFirst();
  return dynamic_cast<TAttrNode*>(P);   
}

//
TAttrNode *TAttrId::SearchById(
  svl::TString Id,
  svl::TString NodeTypeRoot,
  bool         Recursive
)
{
  TNode *P = TNodeSearch(&GetNode())
   .SearchNearParentByType(NodeTypeRoot)
    .SearchChildren()
     .SearchById(Id,Recursive)
      .GetFirst();

  return dynamic_cast<TAttrNode*>(P);   
}

//
TAttrNode *TAttrId::SearchChildById(
  svl::TString ParentNodeType,
  TAttrNode   *CurrNode,
  svl::TString Id,
  bool         Recursive
)
{
  TNode *P = TNodeSearch(CurrNode)
   .SearchNearThisOrParentByType(ParentNodeType)
    .SearchChildren()
     .SearchById(Id,Recursive)
      .GetFirst();
     
  return dynamic_cast<TAttrNode*>(P);
}

//
TAttrNode *TAttrId::SearchChildByTypeAndId(
  svl::TString ParentNodeType,
  TAttrNode   *CurrNode,
  svl::TString ChildType,
  svl::TString ChildId,
  bool         Recursive
)
{
  TNode *P = TNodeSearch(CurrNode)
   .SearchNearThisOrParentByType(ParentNodeType)
    .SearchChildren()
     .SearchByAttrNameAndValue(attrName_NodeType,ChildType,Recursive)
     .SearchById(ChildId)
     .GetFirst();
     
  return dynamic_cast<TAttrNode*>(P);
}

// TAttrNodeObject ////////////////////////////////////////////////////////////

//
bool TAttrNodeObjectBase::GetValueByAttrName(svl::TString &AttrName,svl::TString &Value)
{
  if (AttrName.CompareIC(GetAttrName())) {
    Value = &GetValueAsNode();
    return true;
  }
  return false;
}

//
bool TAttrNodeObjectBase::GetValueNodeByAttrName(svl::TString &AttrName,TNode *&Value)
{
  if (AttrName.CompareIC(GetAttrName())) {
    Value = &GetValueAsNode();
    return true;
  }
  return false;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// TAttrNodeArrayBase /////////////////////////////////////////////////////////

//
bool TAttrNodeArrayBase::GetValueByAttrName(svl::TString &AttrName,svl::TString &Value)
{
  if (AttrName.CompareIC(GetAttrName())) {
    Value = &GetValueAsNodeArray();
    return true;
  }
  return false;
}

//
bool TAttrNodeArrayBase::GetValueNodeArrayByAttrName(svl::TString &AttrName,TNodeArray *&Value)
{
  if (AttrName.CompareIC(GetAttrName())) {
    Value = &GetValueAsNodeArray();
    return true;
  }
  return false;
}

//
void TAttrNodeArrayBase::AddAttrInfo(svl::TInfoParam &Info_) 
{ 
  int InfoParamGroup = infoParamGroup_Default;
  TNodeArray &NodeArray = GetValueAsNodeArray();

///**********  
  if (GetAttrName() == attrName_OldChildren){
    if (NodeArray.Count() == 0) {
      return;
    }
    InfoParamGroup = infoParamGroup_Child;
  }
//*************/
  
  svl::TInfoParam Info = Info_.AddClass(
    GetAttrName(),&NodeArray,InfoParamGroup
  );

  for (int N = 0; N < NodeArray.Count(); N++) {
    Info.Add(
      svl::TString() << GetAttrName() << "[" << N << "]",
      NodeArray.Get(N),
      infoParamGroup_Default
    );
  }
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// TAttrNode //////////////////////////////////////////////////////////////////

//
TAttr *TAttrNode::SearchAttr(svl::TString &AttrName,int &OutNAttr)
{
  for (OutNAttr = 0; OutNAttr < attrArray.Count(); OutNAttr++) {
    TAttr &Attr = attrArray.Get(OutNAttr);
    
    if (AttrName.CompareIC(Attr.GetAttrName())) {
      return &Attr;
    }
  }
  return NULL;
}

/**********************
//
TAttrFuncBase *TAttrNode::SearchFunc(svl::TString FuncName)
{
  for (int N = 0; N < funcArray.Count(); N++) {
    TAttrFuncBase &Func = funcArray.Get(N);
    
    if (FuncName.CompareIC(Func.GetAttrName())) {
      return &Func;
    }
  }
  return NULL;
}

//
void TAttrNode::CallFunc(const char *FuncName,TAttrUserParam &UserParam)
{
  TAttrFuncBase *Func = SearchFunc(FuncName);
 
  if (Func) {
    Func->CallFunc(UserParam);
  }  
  else {
    CallChildrenFunc(FuncName,UserParam);
  }
}
**********************************/

//
void TAttrNode::AddAttrPointer(TAddAttrPointer &Param) 
{
  attrArray.AddAttrPointer(Param);
}

//
void TAttrNode::AddPossibleReferences(TAddPossibleReferences &Param) 
{ 
  Param.Add(this);
  attrArray.AddPossibleReferences(Param);
}

/***************************
//
void TAttrNode::CallChildrenFunc(const char *FuncName,TAttrUserParam &UserParam)
{
  for (int N = 0; N < Children_Count(); N++) {
    TAttrNode *Child = dynamic_cast<TAttrNode*>(&Children_Get(N));
    
    if (Child) {
      TAttrFuncBase *Func = Child->SearchFunc(FuncName);
     
      if (Func) {
        Func->CallFunc(UserParam);
      }  
      else {
        Child->CallChildrenFunc(FuncName,UserParam);
      }
    }
  }
}
*******************************/

//
svl::TInfoParam TAttrNode::AddInfoTo(svl::TInfoParam Info_)
{
  svl::TInfoParam Info = TNode::AddInfoTo(Info_);

  for (int N = 0; N < attrArray.Count(); N++) {
    TAttr &Attr = attrArray.Get(N);
    Attr.AddAttrInfo(Info);
  }  
  
  return Info;
}

//
void TAttrNode::CopyAttrFrom(const prs::TNode *From_)
{
  TAttrNode *From = const_cast<TAttrNode*>(dynamic_cast<const TAttrNode*>(From_));

  for (int N = 0; N < attrArray.Count(); N++) {
    TAttr &AttrThis = attrArray.Get(N);
    TAttr &AttrFrom = From->attrArray.Get(N);
    
    AttrThis.CopyAttrFrom(&AttrFrom);
  }
}

//
svl::TString TAttrNode::GetNodeType()
{
  for (int N = 0; N < attrArray.Count(); N++) {
    TAttrNodeTypeBase *AttrNodeType = dynamic_cast<TAttrNodeTypeBase*>(&attrArray.Get(N));
    
    if (AttrNodeType) {
      return AttrNodeType->GetValue();
    }
  }
  return "";
}

//
const char* TAttrNode::GetNodeTypeEx()
{
  for (int N = 0; N < attrArray.Count(); N++) {
    TAttrNodeTypeBase *AttrNodeType = dynamic_cast<TAttrNodeTypeBase*>(&attrArray.Get(N));
    
    if (AttrNodeType) {
      return AttrNodeType->GetValueEx();
    }
  }
  return "";
}

/***************************
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

// TNodeString ////////////////////////////////////////////////////////////////
const char *TNodeString::attrName_Null = "Null";
const char *TNodeString::attrName_Value = "Value";

// TNodeInteger ///////////////////////////////////////////////////////////////
const char *TNodeInteger::attrName_Null = "Null";
const char *TNodeInteger::attrName_Value = "Value";

// TNodeDouble ////////////////////////////////////////////////////////////////
const char *TNodeDouble::attrName_Null = "Null";
const char *TNodeDouble::attrName_Value = "Value";

// TNodeDateTime //////////////////////////////////////////////////////////////
const char *TNodeDateTime::attrName_Null = "Null";
const char *TNodeDateTime::attrName_Value = "Value";
*********************************/